local table_insert = table.insert
local table_concat = table.concat
local gmatch = string.gmatch
local MDX
local Parser_manager = {}

Parser_manager.init = function()
	if not INPUT_PATH then
		log.error('请拖入需要分析的文件夹')
		return
	end

	local output_path_parent = fs.path(('%s\\output'):format( CURRENT_PATH ))
	if not fs.is_directory( output_path_parent ) then
		fs.create_directory( output_path_parent )
	end

	local input_path = INPUT_PATH

	local dir_name
	for i = #input_path, 1, -1 do
		if input_path:sub(i, i) == '\\' then
			dir_name = input_path:sub(i+1)
			break
		end
	end
	local output_path = ('%s\\output\\%s'):format( CURRENT_PATH, dir_name )
	MDX = require 'script.mdx.mdx_parser'
	MDX.init{
		input_path = input_path,
		output_path = output_path,
		dir = dir_name,
	}

	return true
end

local function for_directory(path, func, leaf)
	for file in (leaf and (path / leaf) or path):list_directory() do
		local leaf = (leaf and (leaf / file:filename()) or file:filename())
		if fs.is_directory(file) then
			for_directory(path, func, leaf)
		else
			func(file)
		end
	end
end

---根据传入的文件夹，整理mdx文件
Parser_manager.collect_mdx = function ()
	
	log.info('分析文件MDX开始...')

	local temp_path = MDX.output_path
	if fs.is_directory( temp_path ) then
		fs.remove_all( temp_path )
	end
	fs.create_directory( temp_path )

	local error_file = {}
	for_directory( MDX.input_path, function( file )
		local filename = file:filename():string()
		local filetype = Utility.Get_filetype( filename )
		if filetype and filetype:lower() == 'mdx' then
			local mdx = MDX.new( file:string() )
			local suc = pcall( mdx.change_blp_paths, mdx, filename:sub(1, -5) )
			if not suc then
				table_insert(error_file, mdx.path)
			end
		end
	end)
	if #error_file > 0 then
		local file = io.open( ('%s\\output\\%s(error).txt'):format( CURRENT_PATH, MDX.dir ), 'w' )
		file:write('以下文件解析失败：\n')
		file:write( table_concat(error_file, '\n') )
		file:close()
	end
	
	log.info('分析文件MDX结束...')
end

---根据传入的文件夹，整理mdx文件
---不会更改blp名称
Parser_manager.collect_mdx_2 = function ()
	
	log.info('分析文件MDX开始...')

	local temp_path = MDX.output_path
	if not fs.is_directory( temp_path ) then
		fs.create_directory( temp_path )
	end

	local error_file = {}
	for_directory( MDX.input_path, function( file )
		local filename = file:filename():string()
		local filetype = Utility.Get_filetype( filename )
		if filetype and filetype:lower() == 'mdx' then
			local mdx = MDX.new( file:string() )
			local suc = pcall( mdx.collect_blp_paths, mdx, filename:sub(1, -5) )
			if not suc then
				table_insert(error_file, mdx.path)
			end
		end
	end)
	if #error_file > 0 then
		local file = io.open( ('%s\\output\\%s(error).txt'):format( CURRENT_PATH, MDX.dir ), 'w' )
		file:write('以下文件解析失败：\n')
		file:write( table_concat(error_file, '\n') )
		file:close()
	end
	
	log.info('分析文件MDX结束...')
end


--对文件键进行整理，解析doo后，会把非doo中出现的模型全部进行删除
Parser_manager.save_doo_model = function ()
	log.info('分析解析doo开始...')

	local doo_ini_path = ('%s\\table\\doodad.ini'):format( INPUT_PATH )
	local doo_ini = fs.path(doo_ini_path)
	if not fs.exists( doo_ini ) then
		log.error('目标文件夹内不存在doodad.ini')
		return
	end


	local all_mdx_paths = {}
	local all_paths = {}


	for line in io.lines(doo_ini_path) do
		if line:sub(1, 4) == 'file' then
			local path = line:match('"(.+)"')
			if path then
				path = path:sub(1, -1)
				if path ~= '' then
					path = path:gsub('\\\\', '\\')
					
					all_mdx_paths[path] = true
				end
			end
		end
	end

	local destructable_ini_path = ('%s\\table\\destructable.ini'):format( INPUT_PATH )
	local destructable_ini = fs.path(destructable_ini_path)
	if fs.exists( destructable_ini ) then
		for line in io.lines(destructable_ini_path) do
			if line:sub(1, 4) == 'file' then
				local path = line:match('"(.+)"')
				if path then
					path = path:sub(1, -1)
					if path ~= '' then
						path = path:gsub('\\\\', '\\')
						
						all_mdx_paths[path] = true
					end
				end
			end
		end
	end

	local paths = {
		'terrainart',
		'ui',
		'replaceabletextures',
	}
	for _, path in ipairs(paths) do
		local _path = fs.path( MDX.input_path / 'resource' / path )
		if fs.exists(_path) then
			if fs.is_directory(_path) then
				for_directory(_path, function (file)
					file = file:string()
					local _, index = file:find('resource')
					local sflag = file:sub(index+2):lower()
					all_paths[sflag] = true
				end)
			end
		end
	end

	
	for name in pairs(all_mdx_paths) do
		local path = ('%s\\resource\\%s'):format( INPUT_PATH, name )
		local exists
		if fs.exists( fs.path(path) ) then
			exists = true
		else
			if name:sub(-4):lower() == '.mdl' then
				name = name:sub(1, -5) .. '.mdx'
			end
			local path = ('%s\\resource\\%s'):format( INPUT_PATH, name )
			if fs.exists( fs.path(path) ) then
				exists = true
			end
		end

		if exists then
			local path = ('%s\\resource\\%s'):format( INPUT_PATH, name )
			local mdx = MDX.new( path )
			for _, blp in ipairs(mdx.blps) do
				all_paths[blp:lower()] = true
			end
			all_paths[name:lower()] = true
		end
	end

	local temp_path = MDX.output_path
	if fs.is_directory( temp_path ) then
		fs.remove_all( temp_path )
	end
	fs.create_directory( temp_path )
	
	local function for_directory(path, func, leaf)
		for file in (leaf and (path / leaf) or path):list_directory() do
			local old_leaf = leaf
			local leaf = (leaf and (leaf / file:filename()) or file:filename())
			if old_leaf then
				local parent_path = fs.path( MDX.output_path / old_leaf )
				if not fs.exists( parent_path ) then
					fs.create_directory(parent_path)
				end
			end
			if fs.is_directory(file) then
				if leaf:string() ~= 'resource' then
					for_directory(path, func, leaf)
				end
			else
				func(file, old_leaf and old_leaf:string())
			end
		end
	end

	for_directory( MDX.input_path, function( file, leaf_string )
		local filename = file:filename():string()
		if leaf_string then
			local parent_path = fs.path( MDX.output_path / leaf_string )
			fs.copy_file( file, fs.path( parent_path / filename ), true )
		else
			fs.copy_file( file, fs.path( MDX.output_path / filename ), true )
		end
	end)

	local findcount = 0
	local had_found = {}
	local origin_sum = 0
	local not_found = {}

	--输出 resource文件下的东西
	local function for_directory(path, func, leaf)
		for file in (leaf and (path / leaf) or path):list_directory() do
			local old_leaf = leaf
			local leaf = (leaf and (leaf / file:filename()) or file:filename())
			if old_leaf then
				local parent_path = fs.path( MDX.output_path / 'resource' / old_leaf )
				if not fs.exists( parent_path ) then
					fs.create_directory(parent_path)
				end
			end
			if fs.is_directory(file) then
				for_directory(path, func, leaf)
			else
				func(file, old_leaf and old_leaf:string())
			end
		end
	end
	fs.create_directory(MDX.output_path / 'resource')
	for_directory( MDX.input_path / 'resource', function( file )
		local sfile = file:string()
		local _, index = sfile:find('resource')
		local sflag = sfile:sub(index+2):lower()
		if all_paths[sflag] and not had_found[sflag] then
			findcount = findcount + 1
			had_found[sflag] = true

			pcall(function ()
				fs.copy_file( file, fs.path( MDX.output_path / 'resource' / sflag ), true )
			end)
		end
	end)

	for name in pairs(all_paths) do
		origin_sum = origin_sum + 1
		if not had_found[name:lower()] then
			table.insert(not_found, name)
		end
	end

	if #not_found == 0 then
		log.info('找到了全部需要的文件')
	else
		table.sort(not_found, function(sec, fir)
			return sec < fir
		end)
		log.info('文件有缺...')
		local error_file = {}
		table.insert(error_file, ('应该有的文件数:%s，实际找到文件数:%s -->'):format( origin_sum, findcount ))
		for k, v in ipairs(not_found) do
			table.insert(error_file, v)
		end
		
		local file = io.open( ('%s\\output\\%s(error).txt'):format( CURRENT_PATH, MDX.dir ), 'w' )
		file:write('以下文件解析失败：\n')
		file:write( table_concat(error_file, '\n') )
		file:close()

	end
	log.info('分析解析doo结束...')

end

local show_objects_info = function (objects, show_callback)
	local new_objects = {}
    for path, data in pairs(objects) do
        new_objects[#new_objects+1] = table.deepcopy(data)
        new_objects[#new_objects].path = path
    end
    local score = {
        ['mdx'] = 1,
        ['blp'] = 2,
        ['tga'] = 3,
        ['png'] = 4,
    }
    table.sort(new_objects, function (sec, fir)
        if sec.type == fir.type then
            return sec.path < fir.path
        else
            local s2 = score[sec.type] or 5
            local s1 = score[fir.type] or 5
            if s2 < s1 then
                return true
            elseif s2 == s1 then
                return sec.path < fir.path
            end
        end
        return false
	end)

	local all_count = 0
	local exist_count = 0
	
	for _, data in ipairs(new_objects) do
		if data.exist then
			exist_count = exist_count + 1
		end
		all_count = all_count + 1

		if show_callback then
			show_callback(data)
		end

    end

	-- log.info(('总共找到%s个文件，实际上有%s个文件'):format(all_count, exist_count))
end

--记录目标文件夹下所有的mdx资源
--path：目标路径
--[[
	name[path] = {
		type = 'mdx'/'blp'/'tga'/ 其他,
		mdx = {},	如果是一个贴图时，对应其引用模型，模型可能多个
		blp = {},	如果是一个模型时，对应其引用的贴图，贴图一般多个
		quote_count = 1,	被引用次数，
		quote_files = {},	在那些个文件中被引用
		exist = true,	该资源存在(模型可能链接到一个不存在的贴图资源)
	}
]]
Parser_manager.analysis_resource_files = function()
	local objects = {}
	local path = MDX.input_path / 'resource'
	local path_str = path:string():lower()

	local record_mdx, record_file, get_free_object
	get_free_object = function ()
		return {
			quote_files = {},
			quote_count = 0,
		}
	end

	record_mdx = function ( file_path )
		file_path = file_path:lower()
		local file_name = Utility.get_file_relative_path( file_path, path_str )
		if not objects[file_name] then
			objects[file_name] = get_free_object()
			objects[file_name].type = 'mdx'
			objects[file_name].blp = {}
			objects[file_name].exist = true
		end
		local mdx = MDX.new( file_path )
		for _, blp in ipairs(mdx.blps) do
			blp = blp:lower()
			record_file(blp, true, file_name)

			objects[file_name].blp[#objects[file_name]+1] = blp
			objects[blp].mdx[#objects[blp].mdx+1] = file_name
			objects[blp].quote_count = objects[blp].quote_count + 1
		end
	end

	record_file = function ( file_path, not_exist, quote_file )
		file_path = file_path:lower()
		local file_name = Utility.get_file_relative_path( file_path, path_str )
		if not objects[file_name] then
			objects[file_name] = get_free_object()
			local _type = Utility.Get_filetype( file_name )
			objects[file_name].type = _type:lower()
			objects[file_name].mdx = {}
		end
		if not not_exist then
			objects[file_name].exist = true
		end
		objects[file_name].quote_file = quote_file
	end

	for_directory( path, function( file )
		local filename = file:filename():string()
		local filetype = Utility.Get_filetype( filename )
		filetype = filetype:lower()
		if filetype and (filetype:lower() == 'mdx' or filetype:lower() == 'mdl') then
			record_mdx( file:string() )
		else
			record_file( file:string(), nil, filename )
		end
	end)

	return objects
end

Parser_manager.print_analysis_files = function()
	--全部的资源资源
	-- local objects = Parser_manager.analysis_resource_files()
	-- show_objects_info(objects)
	--代码索引
	-- local objects, vague_objects = Parser_manager.analysis_code_quote_files()
	-- show_objects_info(objects)
	-- log.info('-----------------> 模糊搜索')
	-- for _, data in ipairs(vague_objects) do
	-- 	print(data.path, data.quote_file)
	-- end
	--物编
	local objects = Parser_manager.analysis_mpq_quote_files()
	show_objects_info(objects, function (data)
		if data.quote_count > 0 then
			log.info(('%s(%s)'):format(data.path, data.quote_count))
		else
			log.info(('%s'):format(data.path))
		end
		if data.blp then
			for _, blp in ipairs(data.blp) do
				log.info(('\t- %s'):format(blp))
			end
		end
		if data.mdx then
			for _, mdx in ipairs(data.mdx) do
				log.info(('\t-> %s'):format(mdx))
			end
		end
		if data.quote_files then
			for key, mdx in ipairs(data.quote_files) do
				log.info(('\t->> %s  %s'):format(key, mdx))
			end
		end
	end)
end

--分析代码中，哪些资源被引用了
Parser_manager.analysis_code_quote_files = function ()
	
	local objects = {}
	local get_free_object = function ()
		return {
			quote_count = 0,
			quote_files = {},
		}
	end

	--找到所有的资源文件的头部文件路径形式，当模糊辨认时，需要通过这个来
	local resource_path = MDX.input_path / 'resource'
	local file_head_paths = {}
	for file in resource_path:list_directory() do
		if fs.is_directory(file) then
			file_head_paths[file:filename():string():lower()] = true
		end
	end

	--资源文件的后缀类型
	local resource_types = {
		['mdx'] = true,
		['mdl'] = true,
		['blp'] = true,
		['tga'] = true,
		['png'] = true,
	}

	
	local vague_objects = {}

	local analysis_file = function ( str, str_file )
		str = str:lower()
		local filetype = Utility.Get_filetype( str )
		filetype = filetype:lower()
		
		if resource_types[filetype] then
			local is_ready

			if filetype == 'mdx' or filetype == 'mdl' then
				local str_1 = str:sub(1, -4) .. 'mdx'
				local str_2 = str:sub(1, -4) .. 'mdl'
				if fs.exists(resource_path/str_1) or Mpq.is_origin(str_1) then
					str = str_1
					is_ready = true
				elseif fs.exists(resource_path/str_2) or Mpq.is_origin(str_2) then
					str = str_2
					is_ready = true
				else
					is_ready = false
				end
			elseif filetype == 'blp' or filetype == 'tga' then
				local str_1 = str:sub(1, -4) .. 'blp'
				local str_2 = str:sub(1, -4) .. 'tga'
				if fs.exists(resource_path/str_1) or Mpq.is_origin(str_1) then
					str = str_1
					is_ready = true
				elseif fs.exists(resource_path/str_2) or Mpq.is_origin(str_2) then
					str = str_2
					is_ready = true
				else
					is_ready = false
				end
			end

			local origin_str = str
			if fs.exists(resource_path/str) or Mpq.is_origin(str) then
				is_ready = true
			else

				local models = {
					'%%s',
					'%%0?%.?%d?%.?f',
					'%%0?%.?%d?%.?d',
				}
				for _, model in ipairs(models) do
					if str:match(model) then
						local s = str:match(model)
						s = s:gsub('%%', '%%%%')
						str = str:sub(1, str:find(s)-1)
						is_ready = false
					end
				end
				if is_ready == nil then
					is_ready = true
				end

			end

			if is_ready then
				if not objects[str] then
					objects[str] = get_free_object()
				end
				objects[str].quote_files[str_file] = (objects[str].quote_files[str_file] or 0) + 1
				objects[str].quote_count = objects[str].quote_count + 1

			else
				table.insert(vague_objects, {
					path = str,
					origin = origin_str,
					quote_file = str_file,
				})
				-- log.info('插入模糊辨认 1', str, origin_str, str_file)
			end
		else
			--模糊辨认
			local origin_str = str
			local res = pcall(fs.exists, resource_path/str)
			if res and not pcall(fs.is_directory, resource_path/str) then
				if not objects[str] then
					objects[str] = get_free_object()
				end
				objects[str].quote_files[str_file] = (objects[str].quote_files[str_file] or 0) + 1
				objects[str].quote_count = objects[str].quote_count + 1
			else
	
				if file_head_paths[str] then
					-- table.insert(vague_objects, {
					-- 	path = str,
					-- 	origin = origin_str,
					-- 	quote_file = str_file,
					-- })
					-- log.info('插入模糊辨认 2', str, origin_str, str_file)
				end

			end

		end
	end

	local code_paths = {
		'BaseScripts',
		'scripts',
		'物编',
	}
	local ignore_files = {
		['scripts\\effect_data.lua'] = true,
	}
	
	local _ignore_files = {}
	for name in pairs(ignore_files) do
		_ignore_files[('%s\\%s'):format(MDX.input_path:string(), name):lower()] = true
	end

	for _, _p in ipairs(code_paths) do
		local new_path = MDX.input_path / _p
		for_directory( new_path, function( file )
			local str_file = file:string()
			if not _ignore_files[str_file:lower()] then
				local file = io.open(str_file, 'r')
				local content = file:read('*a')
				file:close()
				for str in string.gmatch(content, '\'.-\'') do
					str = str:gsub('\\\\', '\\')
					str = str:sub(2, -2)
					analysis_file( str, str_file )
				end
				for str in string.gmatch(content, '\".-\"') do
					str = str:gsub('\\\\', '\\')
					str = str:sub(2, -2)
					analysis_file( str, str_file )
				end
				for str in string.gmatch(content, '%[%[.-%]%]') do
					str = str:sub(3, -3)
					analysis_file( str, str_file )
				end
				for str in string.gmatch(content, '%[=%[.-%]=%]') do
					str = str:sub(4, -4)
					analysis_file( str, str_file )
				end
			end
		end)
	end

	vague_objects = {}
	return objects, vague_objects
end

--分析物编中，哪些资源被引用了
Parser_manager.analysis_mpq_quote_files = function ()

	local objects = {}
	local get_free_object
	get_free_object = function ()
		return {
			quote_files = {},
			quote_count = 0,
		}
	end

	--解析后的doo文件信息
	local doodads = Mpq.analysis_doo()
	--地形装饰物，可破坏物
	local file_nemas = {
		'doodad.ini',
		'destructable.ini',
	}
	local doo_ini_data = {}
	for _, name in ipairs(file_nemas) do
		local data = Ini_reader.load(('%s\\table\\%s'):format(INPUT_PATH, name))
		for k, v in pairs(data) do
			doo_ini_data[k] = v
		end
	end

	--资源文件的后缀类型
	local resource_types = {
		['mdx'] = true,
		['mdl'] = true,
		['blp'] = true,
		['tga'] = true,
	}

	local resource_path = MDX.input_path / 'resource'
	local analysis_file = function ( str, str_file )
		str = str:lower()
		local filetype = Utility.Get_filetype( str )
		filetype = filetype:lower()
		
		if resource_types[filetype] then
			local is_ready

			if filetype == 'mdx' or filetype == 'mdl' then
				local str_1 = str:sub(1, -4) .. 'mdx'
				local str_2 = str:sub(1, -4) .. 'mdl'
				if fs.exists(resource_path/str_1) or Mpq.is_origin(str_1) then
					str = str_1
					is_ready = true
				elseif fs.exists(resource_path/str_2) or Mpq.is_origin(str_2) then
					str = str_2
					is_ready = true
				else
					is_ready = false
				end
			elseif filetype == 'blp' or filetype == 'tga' then
				local str_1 = str:sub(1, -4) .. 'blp'
				local str_2 = str:sub(1, -4) .. 'tga'
				if fs.exists(resource_path/str_1) or Mpq.is_origin(str_1) then
					str = str_1
					is_ready = true
				elseif fs.exists(resource_path/str_2) or Mpq.is_origin(str_2) then
					str = str_2
					is_ready = true
				else
					is_ready = false
				end
			end
			
			if fs.exists(resource_path/str) or Mpq.is_origin(str) then
				is_ready = true
			end

			if is_ready then
				if not objects[str] then
					objects[str] = get_free_object()
				end
				objects[str].quote_files[str_file] = (objects[str].quote_files[str_file] or 0) + 1
				objects[str].quote_count = objects[str].quote_count + 1
			end
		end
	end
	local doo_tables = {
		doodads.normal_doos,
		doodads.special_doos,
	}
	local no_repetition_ids = {}
	for _, doo_tbl in ipairs(doo_tables) do
		for _, data in ipairs(doo_tbl) do
			no_repetition_ids[data.id] = (no_repetition_ids[data.id] or 0) + 1
			if doo_ini_data[data.id] then
				for k, v in pairs(doo_ini_data[data.id]) do
					local str = tostring(v):gsub('\\\\', '\\')
					str = str:sub(3, -2)
					analysis_file(str, 'doodad.ini')
				end
			else
				-- log.error('找到一个在doo文件中存在，但没有被ini文件记录的地形装饰物id：'..data.id)
			end
		end
	end

	-- for id, data in pairs(doo_ini_data) do
	-- 	for k, v in pairs(data) do
	-- 		local str = tostring(v):gsub('\\\\', '\\')
	-- 		str = str:sub(3, -2)
	-- 		analysis_file(str, 'doodad.ini')
	-- 	end
	-- end

	-- local id, c
	-- for k, v in pairs(no_repetition_ids) do
	-- 	if not id then
	-- 		id = k
	-- 		c = v
	-- 	else
	-- 		if v > c then
	-- 			id = k
	-- 			c = v
	-- 		end
	-- 	end
	-- end
	-- log.info( ('最多被使用的模型是%s(%s),name=%s,file=%s'):format(id, c, doo_ini_data[id].Name, doo_ini_data[id].file) )

	return objects
end

Parser_manager.analysis_all_reources = function ( remove_resource )
	local s_path = ([[%s\map]]):format(INPUT_PATH)
    local path = fs.path(s_path)
    if not fs.exists( path ) then
		log.error('只支持 w3x2Lni 格式文件夹')
		return false
	end

	print('---------------- 开始 分析所有资源')
    -- Parser_manager.print_analysis_files()
	--分析所有资源，然后得到其信息组
	local all_reource_objects = Parser_manager.analysis_resource_files()
	
	show_objects_info(all_reource_objects, function (data)
		log.write(('分析所有资源 resource： %s(%s)'):format(data.path, data.quote_count))
		if data.mdx then
			for _, mdx in ipairs(data.mdx) do
				log.write( ('\t %s->%s'):format(_, mdx) )
			end
		end
		if data.blp then
			for _, mdx in ipairs(data.blp) do
				log.write( ('\t %s->%s'):format(_, mdx) )
			end
		end
	end)

	print('---------------- 开始 分析代码')
	--分析代码
	local code_objects, code_vague_objects = Parser_manager.analysis_code_quote_files()
	-- 手动插入模糊，这个文件夹下面的不删除
	for _, str in ipairs( {
		-- 'image', 
		'terrainart', 'sys', 'interface', 'fonts', 'doodads',
		'replaceabletextures\\lightning', 
		'replaceabletextures\\lordaerontree',
		'replaceabletextures\\selection', 
		'replaceabletextures\\Splats', 
		'replaceabletextures\\cliff', 
		'blend',
		'system',
		'dekanLighting',
	} ) do
		table.insert(code_vague_objects, {
			path = ('%s\\'):format(str),
			origin = ('%s\\'):format(str),
			quote_file = ('%s\\'):format(str),
		})
	end
	local new_code_vague_objects = {}
	for _, data in ipairs(code_vague_objects) do
		new_code_vague_objects[data.path] = data
	end


	show_objects_info(code_objects, function (data)
		log.write(('分析所有代码 resource： %s(%s)'):format(data.path, data.quote_count))
		if data.mdx then
			for _, mdx in ipairs(data.mdx) do
				log.write( ('\t %s->%s'):format(_, mdx) )
			end
		end
		if data.blp then
			for _, mdx in ipairs(data.blp) do
				log.write( ('\t %s->%s'):format(_, mdx) )
			end
		end
	end)
	log.write('---------------------- 分析所有代码模糊查找')
	show_objects_info(new_code_vague_objects, function (data)
		log.write(('分析所有代码模糊查找 resource： %s(%s)'):format(data.path, data.quote_count))
		if data.mdx then
			for _, mdx in ipairs(data.mdx) do
				log.write( ('\t %s->%s'):format(_, mdx) )
			end
		end
		if data.blp then
			for _, mdx in ipairs(data.blp) do
				log.write( ('\t %s->%s'):format(_, mdx) )
			end
		end
	end)


	print('---------------- 分析相关物编')
	local mpq_objects = Parser_manager.analysis_mpq_quote_files()

	show_objects_info(mpq_objects, function (data)
		log.write(('分析相关物编 resource： %s(%s)'):format(data.path, data.quote_count))
		if data.mdx then
			for _, mdx in ipairs(data.mdx) do
				log.write( ('\t %s->%s'):format(_, mdx) )
			end
		end
		if data.blp then
			for _, mdx in ipairs(data.blp) do
				log.write( ('\t %s->%s'):format(_, mdx) )
			end
		end
	end)

	local resource_of_lack = {}
	local search_objects = {
		code_objects,
		mpq_objects,
	}
	for _, objects in pairs(search_objects) do
		for file_path, data in pairs(objects) do
			log.write(('来源：%s, path=%s，存在：%s'):format(_, file_path, all_reource_objects[file_path]))
			if all_reource_objects[file_path] then
				all_reource_objects[file_path].new_quote_count = (all_reource_objects[file_path].new_quote_count or all_reource_objects[file_path].quote_count) + 1
			else
				if data.type == 'mdx' then
					local str_1 = file_path:sub(1, -4) .. 'mdx'
					local str_2 = file_path:sub(1, -4) .. 'mdl'
					if all_reource_objects[str_1] or all_reource_objects[str_2] then
						all_reource_objects[file_path].new_quote_count = (all_reource_objects[file_path].new_quote_count or all_reource_objects[file_path].quote_count) + 1
					else
						if not( Mpq.is_origin(str_1) or Mpq.is_origin(str_2) ) then
							resource_of_lack[file_path] = data
						end
					end
				elseif data.type == 'blp' or data.type == 'tga' then
					local str_1 = file_path:sub(1, -4) .. 'blp'
					local str_2 = file_path:sub(1, -4) .. 'tga'
					if all_reource_objects[str_1] or all_reource_objects[str_2] then
						all_reource_objects[file_path].new_quote_count = (all_reource_objects[file_path].new_quote_count or all_reource_objects[file_path].quote_count) + 1
					else
						if not( Mpq.is_origin(str_1) or Mpq.is_origin(str_2) ) then
							resource_of_lack[file_path] = data
						end
					end
				else
					if Mpq.is_custom(file_path) then
						if file_path:find('rchnathidgreen') then
							local str_1 = file_path:sub(1, -4) .. 'mdx'
							local str_2 = file_path:sub(1, -4) .. 'mdl'
							log.info('1', data.type, data.type == '', tostring(Mpq.is_origin(str_1)), tostring(Mpq.is_origin(str_2)))
						end
						resource_of_lack[file_path] = data
					end
				end
			end
		end
	end

	--执行模糊辨认
	local vague_objects = {}
	for file_path, data in pairs(all_reource_objects) do
		if data.type == 'mdx' then
			if not data.new_quote_count then
				local find
				for path in pairs(new_code_vague_objects) do
					if file_path:match('^'..path) then
						find = true
						data.new_quote_count = 1
						-- log.info( ('模糊辨认 mdx：%s -> %s'):format(file_path, path) )
						vague_objects[file_path] = data
						data.origin_str = path
						break
					end
				end

				if not find then
					--特殊处理头像问题
					if file_path:find('_portrait.') then
						local _start = file_path:find('_portrait.')
						local str_1 = file_path:sub(1, _start-1) .. '.mdx'
						local str_2 = file_path:sub(1, _start-1) .. '.mdl'
						if all_reource_objects[str_1] and all_reource_objects[str_1].new_quote_count or all_reource_objects[str_2] and all_reource_objects[str_2].new_quote_count then
							data.new_quote_count = 1
							-- log.info( ('头像辨认成功：%s -> %s'):format(file_path, path) )
							vague_objects[file_path] = data
							data.origin_str = file_path
							find = true
						end
					end
				end

				if not find then
					for _, blp in pairs(data.blp) do
						all_reource_objects[blp].quote_count = all_reource_objects[blp].quote_count - 1
						-- log.write( ('模糊辨认 失败扣除次数 blp：%s -> %s'):format(blp, all_reource_objects[blp].quote_count) )
					end
				end
			end
		else
			for path in pairs(new_code_vague_objects) do
				if file_path:match('^'..path) then
					data.new_quote_count = 1
					-- log.info( ('模糊辨认 blp：%s -> %s'):format(file_path, path) )
					vague_objects[file_path] = data
					data.origin_str = path
					break
				end
			end
			
		end
	end

	-- local count = 0
	-- show_objects_info(vague_objects, function (data)
	-- 	log.info(('辨认成功：%s(%s)'):format(data.path, data.origin_str))
	-- 	count = count + 1
	-- end)
	-- log.info( ('总共辨认成功 %s 个文件'):format(count) )

	-- local count = 0
	-- show_objects_info(resource_of_lack, function (data)
	-- 	log.info(('缺少 %s(%s)'):format(data.path, data.quote_count))
	-- 	count = count + 1
	-- end)
	-- log.info( ('总共缺少%s个文件'):format(count) )
	--classical_fountain001没mdx解析正确
	log.write('\n')
	log.write('\n')
	local wait_to_remove_objects = {}
	local count = 0
	show_objects_info(all_reource_objects, function (data)
		-- if data.path == [[hero\[hero]tk_hero_03.mdx]] then
		-- 	print(1111, not data.new_quote_count, data.quote_count <= 0, Mpq.is_custom(data.path))
		-- end
		if (not data.new_quote_count) and data.quote_count <= 0 then
			if Mpq.is_custom(data.path) then
				log.write(('即将移除 %s(%s)'):format(data.path, data.quote_count))
				count = count + 1
				if data.mdx then
					for _, mdx in ipairs(data.mdx) do
						log.write( ('\t %s->%s'):format(_, mdx) )
					end
				end
				if data.blp then
					for _, mdx in ipairs(data.blp) do
						log.write( ('\t %s->%s'):format(_, mdx) )
					end
				end
				wait_to_remove_objects[data.path] = true
			end
		end
	end)

	local ignore_files = {
		'lightnings\\LN06.blp',
		'lightnings\\LN00.blp',
		'lightnings\\DrainManaLightning.blp',
		'ReplaceableTextures\\lightning\\drainmanalightning.blp',
		'ReplaceableTextures\\lightning\\LightningArea.blp',
		'AZTextures\\AZ_Lightning2W.blp',
		'AZTextures\\AZ_Lightning1G.blp',
		'Textures\\Laser.blp',
		'Textures\\Hero_LordOfOlympia_N2S_C_target_10.blp',
		'war3mapImported\\lightningarrow.blp',
		'Textures\\Hero_Oblivion_N1S_light.blp',
	}
	for _, name in ipairs(ignore_files) do
		name = ('%s'):format( name:lower() )
		if wait_to_remove_objects[name] then
			wait_to_remove_objects[name] = nil
		end
	end

	log.info( ('总共有%s个文件会被移除'):format(count) )

	if remove_resource then
		local resource_path = MDX.input_path / 'resource'
		local count_2 = 0
		for path in pairs(wait_to_remove_objects) do
			if pcall(fs.exists, resource_path/path) then
				fs.remove(resource_path/path)
				count_2 = count_2 + 1
			end
		end
		log.info( ('计划移除%s个文件，实际移除 %s'):format(count, count_2) )
	end

end

return Parser_manager